我們在昨天已經想好一套實作 Redirect Stdin 的方法,大致上可以分成這幾個步驟:
data 檔案data 檔案func executeInput(input string) error {
    // ...
    args := parseArgs(input)
    // ...
    // 先設好預設的 inputStream
    // 預設是從終端機進行讀取
    inputStream := os.Stdin
    // 如果 args 有大於兩個元素,譬如說 ["python", "<", "data"]
    // 而且倒數第二個(len(args)-2)是 "<"
    // 那就需要重新導向 Stdin
    if len(args) > 2 && args[len(args)-2] == "<" {
        // 檔案名稱是最後一個參數
        // 這邊的 filename = "data"
        filename := args[len(args)-1]
        
        // 1. 用昨天講到的 Open 嘗試開啟檔案
        file, err := os.Open(filename)
        
        // 2. 如果發生錯誤的話(檔案不存在)就回傳錯誤
        if err != nil {
            return err
        }
        // 3. 檔案存在的話就把 inputStream 設為 file 檔案
        inputStream = file
        
        // 4. 執行 python 指令
        // 因為結尾的 < data 不是 python 的參數
        // 所以把最後兩個參數刪掉,只保留前面的 python
        // 此時的 args = ["python"]
        args = args[:len(args)-2]
    }
    cmd := exec.Command(args[0], args[1:]...)
    // 把 Stdin 來源設為 inputStream
    // 如果沒有經過 Redirect,那 inputStream 就是終端機
    // 如果有經過 Redirect,則 inputStream 會是那個檔案
    cmd.Stdin = inputStream
    
    cmd.Stdout = os.Stdout
    cmd.Stderr = os.Stderr
    err := cmd.Run()
    return err
}


因為時間不多所以今天只實作了 Redirect Stdin,但其實 Redirect Stdout 也是差不多的做法,大致上就是 檔案開起來、資料寫進去,有興趣可以自己試試看XD
今天應該是寫最多扣的一天,跟之前一樣有問題歡迎在下方提問,沒問題的話明天就要進入 Signal 的部分了,這部分比較難,各位看倌要有點心理準備哦~